<?php

namespace app\common\model;

use think\Model;
use think\Db;

/**
 * 币种模型
 */
class Wallet extends Model
{

    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';

    protected static function init()
    {
    }

    /**
     * 所有钱包列表
     * @param string $status 指定状态
     * @return array
     */
    public static function walletTokenList($status = null)
    {
        $list = collection(self::where(function ($query) use ($status) {
            if (!is_null($status)) {
                $query->where('status', '=', $status);
            }
        })->order('sort', 'asc')->select())->toArray();
        return $list;
    }

    /**
     * 返回个人用户的钱包列表
    */
    public static function user_wallet($uid)
    {
        $wallet = model('wallet')->where(['uid' => $uid])->select();
        if (empty($wallet)) {
            $wallet_token = Db::name('wallet_token')->where(['status' => 'normal'])->select();
            foreach ($wallet_token as $item) {
                Wallet::create_wallet($item['id'], $uid);
            }
        }

        return $wallet;
    }

    /**
     * 创建钱包
    */
    public static function create_wallet($coin_id, $uid)
    {
        if ($coin_id > 0) {
            $wallet_token[] = WalletToken::get($coin_id);
        } else {
            $wallet_token = WalletToken::walletTokenList();
        }
        foreach ($wallet_token as $wallet) {
            $data = [
                'uid' => $uid,
                'coin_id' => $wallet['id'],
                'createtime' => time(),
                'updatetime' => time()
            ];
            $exist = Db::name('wallet')->where($data)->find();
            if (!$exist) {
                model('wallet')->insert($data);
            }
        }

        return ['error' => 0];
    }

    /**
     * 返回USDT的币种id
    */
    public static function usdt_id()
    {
        return config('usdt_id');
    }

    /**
     * 变更钱包余额
     * @param int    $user_id 会员ID
     * @param int    $money   余额
     * @param int $coin_id 币种ID
     * @param string $from 来自什么操作
     * @param int $from_id 来自操作表或者类型ID
     * @param int $type 分类类目，用于页面展示筛选
     * @param string $mark    备注
     * @param string $money_type 变动的是余额还是冻结余额
     */
    public static function up_coin($user_id, $money, $coin_id, $from = '', $from_id = 0, $type = 0, $mark = '', $money_type = 'balance')
    {
        Db::startTrans();
        try {
            $wallet = self::lock(true)->where(['uid' => $user_id, 'coin_id' => $coin_id])->find();
            if ($wallet) {
                $before = $wallet[$money_type];
                if ($money > 0) {
                    $after = function_exists('bcadd') ? bcadd($wallet[$money_type], $money, 2) : $wallet[$money_type] + $money;
                    model('wallet')->where(['id' => $wallet['id']])->setInc($money_type, $money);
                } elseif ($money < 0) {
                    if ($before < $money) {
                        return ['error' => 1, 'msg' => '您的余额不足..'];
                    }
                    $after = function_exists('bcsub') ? bcsub($wallet[$money_type], abs($money), 2) : $wallet[$money_type] + $money;
                    model('wallet')->where(['id' => $wallet['id']])->setDec($money_type, abs($money));
                } else {
                    $after = $before;
                }

                //写入日志
                if ($from && $type == 0) {
                    $type_id = Db::name('log_type')->where(['mnemonic' => $from])->value('type');
                    if ($type_id) {
                        $type = $type_id;
                    }
                }
                MoneyLog::create(['user_id' => $user_id, 'money' => $money, 'before' => $before, 'after' => $after, 'memo' => $mark, 'from' => $from, 'from_id' => $from_id, 'type' => $type]);
            }
            Db::commit();
            return ['error' => 0];
        } catch (\Exception $e) {
            Db::rollback();
            return ['error' => 0, 'msg' => $e->getMessage()];
        }
    }

    /**
     * 获取某用户的余额
    */
    public static function get_balance($uid, $coin_id, $balance_type = 'balance')
    {
        return Db::name('wallet')->where(['uid' => $uid, 'coin_id' => $coin_id])->value($balance_type);
    }

    /**
     * 转账接口
    */
    public static function transfer_coin($uid, $to_uid, $coin_id, $num)
    {
        if ($to_uid == $uid) {
            return ['error' => 1, 'msg' => '亲，不要给自己转账哟'];
        } else {
            $to_user = model('user')->where(['username' => $to_uid])->find();
            if (!$to_user) {
                $to_user = model('user')->where(['id' => $to_uid])->find();
                if (!$to_user && !is_numeric($to_uid)) {
                    $to_user = model('wallet')->alias('w')->join('user u', 'u.id=w.uid', 'right')->where(['address' => $to_uid, 'coin_id' => $coin_id])->find();
                    if (!$to_user) {
                        return ['error' => 1, 'msg' => '未找到转入的用户'];
                    }
                }
                $balance = Wallet::get_balance($uid, $coin_id);
                if ($balance < $num) {
                    return ['error' => 1, 'msg' => '您的余额不足，无法转账！'];
                }
                $to_balance = Wallet::get_balance($to_uid, $coin_id);
                if ($to_balance == null) {
                    return ['error' => 1, 'msg' => '对方钱包异常，无法转账！'];
                }

                Db::startTrans();
                try {
                    $type_str = 'translate_coin';
                    $bill_id = BillOrder::add_bill($uid, $to_uid, '', 1, $num, $coin_id, 0, $type_str, 3);
                    Wallet::up_coin($uid, -$num, $coin_id, $type_str, $bill_id);
                    Wallet::up_coin($to_uid, $num, $coin_id, $type_str, $bill_id);

                    Db::commit();
                } catch (\Exception $exception) {
                    Db::rollback();
                    return ['error' => 1, 'msg' => $exception->getMessage()];
                }

                return ['error' => 0];
            }
        }
    }

    /**
     * 提现接口
     */
    public static function withdraw_coin($uid, $address, $coin_id, $num)
    {
        if (empty($address)) {
            return ['error' => 1, 'msg' => '用户的钱包地址不能为空！'];
        } else {
            $validateAddress = Trx::validateAddress($address);
            if ($validateAddress['result'] == false) {
                return ['error' => 1, 'msg' => '您输入的提现地址有误！'];
            }

            $user = model('user')->where(['id' => $uid])->find();
            if (!$user) {
                return ['error' => 1, 'msg' => '您的会员信息已失效！'];
            } else {
                $fee = 0;
                $wallet_token = WalletToken::get($coin_id);
                if ($wallet_token['withdraw_fee'] > 0) {
                    if ($wallet_token['withdraw_type'] == 1) {
                        $fee = $wallet_token['withdraw_fee'];
                    } elseif ($wallet_token['withdraw_type'] == 2) {
                        $fee = $num * $wallet_token['withdraw_fee'] * 0.01;
                    }
                }

                $balance = Wallet::get_balance($uid, $coin_id);
                if ($balance < ($num + $fee)) {
                    return ['error' => 1, 'msg' => '您的余额不足，无法提现！'];
                }
                $num += $fee;//扣手续费

                Db::startTrans();
                try {
                    $type_str = 'withdraw_coin';
                    $bill_id = BillOrder::add_bill($uid, $address, '', 1, $num, $coin_id, 0, $type_str, 0);//已扣款状态
                    Wallet::up_coin($uid, -$num, $coin_id, $type_str, $bill_id);

                    Db::commit();
                } catch (\Exception $exception) {
                    Db::rollback();
                    return ['error' => 1, 'msg' => $exception->getMessage()];
                }

                return ['error' => 0];
            }
        }
    }

    /**
     * 提现驳回
    */
    public static function reject($order_id)
    {
        $order = BillOrder::get($order_id);
        if (!$order) {
            return ['error' => 1, 'msg' => '提现订单不存在'];
        } elseif ($order['status'] == 0) {
            Db::startTrans();
            try {
                model('BillOrder')->where(['id' => $order['id']])->update(['status' => 3]);
                Wallet::up_coin($order['uid'], $order['amount'], $order['coin_id'], 'withdraw_reject', $order['id']);
                Db::commit();
                return ['error' => 0];
            } catch (\Exception $exception) {
                Db::rollback();
                return ['error' => 1, 'msg' => $exception->getMessage()];
            }
        } else {
            return ['error' => 1, 'msg' => '该订单状态不允许驳回'];
        }
    }

    /**
     * 提现审核通过
     */
    public static function approved($order_id)
    {
        $order = BillOrder::get($order_id);
        if (!$order) {
            return ['error' => 1, 'msg' => '提现订单不存在'];
        } elseif ($order['status'] == 0) {
            $res = Trx::confirm_withdraw($order_id);
            return $res;
        } else {
            return ['error' => 1, 'msg' => '该订单状态不允许再审核'];
        }
    }

    /**
     * 币价转换
    */
    public static function coin_price_transfer($from_id, $to_id, $number)
    {
        return $number;
    }

    /**
     * 创建币种地址
    */
    public static function create_address($uid, $coin_id)
    {
        if ($coin_id == config('usdt_id')) {
            return Trx::create_address($uid);
        } else {
            return ['error' => 1, 'msg' => '暂无此币地址'];
        }
    }

    /**
     * 获取充值记录
    */
    public static function get_recharge($uid, $coin_id)
    {
        if ($coin_id == config('usdt_id')) {
            return Trx::get_recharge($uid);
        } else {
            return ['error' => 1, 'msg' => '暂无此币充值记录'];
        }
    }
}
